/*
 * Author: xzy
 * Date: 2025-10-11
 * Time: 19:54:43
 * Description: TODO - Add file description here
 */
package com.xtedu.examproject.controller;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;

// ... other imports
@WebServlet("/errorHandler")
public class ErrorHandler extends HttpServlet {
    private static final Logger logger = LoggerFactory.getLogger(ErrorHandler.class);

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        handleError(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        handleError(request, response);
    }

    private void handleError(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // 1. 获取错误信息（这部分逻辑不变）
        Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
        String errorMessage = (String) request.getAttribute("javax.servlet.error.message");
        Throwable exception = (Throwable) request.getAttribute("javax.servlet.error.exception");
        String requestUri = (String) request.getAttribute("javax.servlet.error.request_uri");

        // 2. 记录日志（这部分逻辑不变）
        if (exception != null) {
            logger.error("请求URI [{}] 发生未处理的异常", requestUri, exception);
        } else {
            logger.warn("请求URI [{}] 发生HTTP错误: {} - {}", requestUri, statusCode, errorMessage);
        }

        // 3. 检查响应是否已经被提交
        if (response.isCommitted()) {
            logger.error("无法转发到错误页面，因为响应已经提交。");
            return;
        }

        // 4. 重置响应，清除任何可能已写入的头部和内容
        response.reset();

        // 5. 重新设置响应状态和内容类型（因为 reset() 会清除它们）
        response.setStatus(HttpServletResponse.SC_OK); // 或者你也可以设置成 statusCode
        response.setContentType("text/html;charset=UTF-8");

        // 6. 根据环境选择错误页面
        String environment = getServletContext().getInitParameter("environment");
        String errorPage;
        if ("production".equals(environment)) {
            errorPage = "/error.jsp";
        } else {
            errorPage = "/error_debug.jsp";
        }

        // 7. 将错误信息放入请求属性，以便JSP使用
        request.setAttribute("statusCode", statusCode);
        request.setAttribute("errorMessage", errorMessage);
        request.setAttribute("exception", exception);

        // 8. 现在可以安全地转发了
        try {
            request.getRequestDispatcher(errorPage).forward(request, response);
        } catch (Exception e) {
            // 如果转发本身也失败了，记录日志
            logger.error("转发到错误页面 [{}] 时发生异常", errorPage, e);
        }
    }
}
